home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
176-200
/
disk_193
/
zc
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
10KB
|
539 lines
/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to redistribute it freely, with the
* following restrictions:
* 1) No charge may be made other than reasonable charges for reproduction.
* 2) Modified versions must be clearly marked as such.
* 3) The authors are not responsible for any harmful consequences
* of using this software, even if they result from defects in it.
*
* main.c
*
* Main routine, error handling, keyword lookup.
*
*
* Revised: Dec 1988 Joe Montgomery
*
* Revised main.c to use Amiga File System Naming Conventions
* Added ?,C,F switches. ? help
* C force data,bss into Chip memory
* F force data,bss into Fast memory
* To be added -o switch to specify assembly output
*
* other modules:
* Revised out.c to use MOTOROLA assembly directives in order
* to be compatible with C.Gibbs a68k assembler & blink
* Added END statement
* Changed .comm label,size to label DC.x 0
* Revised d2.c so that externs are declared as XREF -----
* Revised g2.c & gen.c to declare all called functions XREF
* (will need to change this to declare only external functions)
*
*
* All changes labeled JMM
*/
#include <stdio.h>
#include "param.h"
#include "nodes.h"
#include "tok.h"
extern short usechipmemory,usefastmemory;
int lineno;
int nmerrors;
int oflags[26];
int xflags[26];
int pflag = 0; /* enable profiling */
static int anydebug;
#define debug oflags['z'-'a']
FILE *input;
FILE *output;
#if CC68
FILE *fopenb();
#define fopen fopenb
#endif
char *inname;
#if NEEDBUF
char my_ibuf[BUFSIZ];
#endif
NODEP cur;
/* JMM changed defines to be compatible with AMIGA */
static char *defines[] = {
"MC68000",
"mc68000",
"SOZOBON",
"MCH_AMIGA",
"AmigaDOS",
NULL
};
static char Version[] =
"zc: Amiga Version 1.01 Copyright (c) 1988 by Sozobon, Limited.\n";
static char Version2[] =
" modified by J.Montgomery. Now generates Motorola compatible \n";
static char Version3[] =
" assembly code.\n";
extern char *outfilename,*errorfile;
main(argc, argv)
char **argv;
{
char *p, *getenv();
int shownames;
int i;
/* JMM added switches to force data,bss into chip or fast memory */
usefastmemory = 0;
usechipmemory = 0; /* don't force data into either chip or fast*/
outfilename = (char *) NULL;
/* JMM force hcc to always print out version */
printf(Version);
if (sizeof(NODE) & 3) {
printf("sizeof NODE not mult of 4\n");
exit(1);
}
/*
* Define the "built-in" macros
*/
for (i=0; defines[i] != NULL; i++)
optdef(defines[i]);
/*
* Parse the INCLUDE environment variable, if present.
*/
if ((p = getenv("INCLUDE")) != NULL){
if( doincl(p) == 1 )exit(0);
}
shownames = 0;
if (isatty(0)) {
write(1, "\33v", 2);
setbuf(stdout, NULL);
}
/* put author here */
while (argc-- > 1) {
argv++;
if(argv[0][0] == '?') {
doopt(&argv[0][0]);
exit(1);
}
if(argv[0][0] == '-')
doopt(&argv[0][1]);
#if CC68
else if (argv[0][0] == '+') {
upstr(&argv[0][1]);
doopt(&argv[0][1]);
}
#endif
else {
if (argc > 1 || shownames) {
shownames++;
printf("%s:\n", argv[0]);
}
if (input != NULL)
fclose(input);
input = fopen(argv[0], ROPEN);
if (input == NULL) {
printf("Cant open %s\n", argv[0]);
exit(1);
}
#if NEEDBUF
setbuf(input, my_ibuf);
#endif
inname = argv[0];
dofile();
}
}
if (input == NULL) {
input = stdin;
output = stdout;
inname = "<STDIN>";
dofile();
}
exit(0);
}
doincl(s)
char *s;
{
char *malloc(), *strcpy();
char buf[256];
char dir[128];
register char *p;
strcpy(buf, s);
/*
* Convert ',' and ';' to nulls
*/
for (p=buf; *p != '\0' ;p++)
if (*p == ',' || *p == ';')
*p = '\0';
p[1] = '\0'; /* double null terminated */
/*
* Grab each directory, make sure it ends with a slash,
* and add it to the directory list.
*/
for (p=buf; *p != '\0' ;p++) {
strcpy(dir, p);
/* JMM use Amiga file naming conventions */
if (dir[strlen(dir)-1] != '/' && dir[strlen(dir)-1] != ':')
strcat(dir, "/");
optincl( strcpy(malloc((unsigned) (strlen(dir) + 1)), dir) );
while (*p != '\0')
p++;
}
}
extern int nodesmade, nodesavail;
extern NODEP deflist[], symtab[], tagtab;
extern NODEP strsave;
extern int level;
dofile()
{
char *scopy();
int i;
out_start(inname);
inname = scopy(inname);
lineno = 1;
nmerrors = 0;
advnode();
level = 0;
program();
dumpstrs(strsave);
out_end();
if (cur && cur->e_token == EOFTOK)
freenode(cur);
sfree(inname);
for (i=0; i<NHASH; i++) {
if (debug>1 && deflist[i]) {
printf("defines[%d]", i);
printlist(deflist[i]);
}
freenode(deflist[i]);
deflist[i] = NULL;
if (debug && symtab[i]) {
printf("gsyms[%d]", i);
printlist(symtab[i]);
}
freenode(symtab[i]);
symtab[i] = NULL;
}
if (debug) {
printf("structs");
printlist(tagtab);
}
freenode(tagtab);
tagtab = NULL;
freenode(strsave);
strsave = NULL;
if (nmerrors) {
printf("%d errors\n", nmerrors);
exit(1);
}
if (nodesmade != nodesavail) {
printf("lost %d nodes!!!\n", nodesmade-nodesavail);
exit(1);
}
/*
printf("Space = %ldK\n", ((long)nodesavail*sizeof(NODE))/1024);
*/
}
dooutfile(s)
char *s;
{
char *malloc(), *strcpy();
outfilename = strcpy(malloc((unsigned)(strlen(s) + 1)), s );
}
doerrorfile(s)
char *s;
{
char *malloc(),*strcpy();
errorfile = strcpy(malloc((unsigned)(strlen(s) + 1)), s);
}
doopt(s)
char *s;
{
register char c;
while ((c = *s++)) {
#ifdef DEBUG
if (c >= 'a' && c <='z') {
oflags[c-'a']++;
anydebug++;
} else
#endif
if ( (c >= 'A' && c <= 'Z') || c == '?') {
switch (c) {
case 'D':
optdef(s);
return;
case 'U':
optundef(s);
return;
case 'I':
doincl(s);
return;
case 'P':
pflag = 1;
continue;
case 'V':
printf("%s %s",Version2,Version3);
continue;
/* JMM added ?,C,F,O,E switches */
case 'E': /* specify error file */
doerrorfile(s);
return(1);
case 'O':
dooutfile(s);
return(1);
case 'C':
if(usefastmemory){
printf(" Can't use both Chip & Fast memory\n");
return(1);
}
usechipmemory = 1;
continue;
case 'F':
if(usechipmemory){
printf(" Can't use both Chip & Fast memory\n");
return(1);
}
usefastmemory = 1;
continue;
case '?':
printf("%s %s",Version2,Version3);
printf(" The Correct Syntax is \n");
printf("zc [FLAGS] SOURCEFILE \n");
printf(" The valid compiler flags are : \n");
printf("\n -Dxxxx Define xxxx\n -Uxxxx Undefine xxxx\n");
printf(" -Ixxxx Include Directory = xxxx\n -P profiler\n");
printf(" -Oxxxx outputfile name = xxxx\n");
printf(" -V display compiler version\n -? Help\n");
printf(" -C force Data,Bss into Chip memory \n");
printf(" -F force Data,Bss into Fast memory \n");
return(1);
continue;
}
#ifdef DEBUG
xflags[c-'A']++;
anydebug++;
#endif
}
}
return(0);
}
errors(s,t)
char *s, *t;
{
optnl();
printf("error in %s on line %d: %s %s\n", inname, lineno, s,t);
nmerrors++;
}
errorn(s,np)
char *s;
NODE *np;
{
optnl();
printf("error in %s on line %d: %s ", inname, lineno, s);
put_nnm(np);
putchar('\n');
nmerrors++;
}
error(s)
char *s;
{
optnl();
printf("error in %s on line %d: %s\n", inname, lineno, s);
nmerrors++;
}
warns(s,t)
char *s, *t;
{
optnl();
printf("warning in %s on line %d: %s %s\n", inname, lineno, s,t);
}
warnn(s,np)
char *s;
NODE *np;
{
optnl();
printf("warning in %s on line %d: %s ", inname, lineno, s);
put_nnm(np);
putchar('\n');
}
warn(s)
char *s;
{
optnl();
printf("warning in %s on line %d: %s\n", inname, lineno, s);
}
fatals(s,t)
char *s, *t;
{
optnl();
printf("fatal error in %s on line %d: %s %s\n", inname, lineno, s,t);
exit(1);
}
fataln(s,np)
char *s;
NODE *np;
{
optnl();
printf("fatal error in %s on line %d: %s ", inname, lineno, s);
put_nnm(np);
putchar('\n');
exit(1);
}
fatal(s)
char *s;
{
optnl();
printf("fatal error in %s on line %d: %s\n", inname, lineno, s);
exit(1);
}
static
optnl()
{
if (anydebug)
putchar('\n');
}
struct kwtbl {
char *name;
int kwval;
int kflags;
} kwtab[] = {
/* must be sorted */
{"asm", K_ASM},
{"auto", K_AUTO},
{"break", K_BREAK},
{"case", K_CASE},
{"char", K_CHAR},
{"continue", K_CONTINUE},
{"default", K_DEFAULT},
{"do", K_DO},
{"double", K_DOUBLE},
{"else", K_ELSE},
{"enum", K_ENUM},
{"extern", K_EXTERN},
{"float", K_FLOAT},
{"for", K_FOR},
{"goto", K_GOTO},
{"if", K_IF},
{"int", K_INT},
{"long", K_LONG},
{"register", K_REGISTER},
{"return", K_RETURN},
{"short", K_SHORT},
{"sizeof", K_SIZEOF},
{"static", K_STATIC},
{"struct", K_STRUCT},
{"switch", K_SWITCH},
{"typedef", K_TYPEDEF},
{"union", K_UNION},
{"unsigned", K_UNSIGNED},
{"void", K_VOID},
{"while", K_WHILE},
{0,0}
};
#define FIRST_C 'a'
#define LAST_C 'z'
struct kwtbl *kwstart[LAST_C-FIRST_C+1];
kw_init()
{
register struct kwtbl *p;
register c;
for (p=kwtab; p->name; p++) {
c = p->name[0];
if (kwstart[c-FIRST_C] == 0)
kwstart[c-FIRST_C] = p;
}
}
kw_tok(tp)
NODE *tp;
{
register struct kwtbl *kp;
register char *nm;
register i;
static first = 0;
nm = tp->n_name;
if (first == 0) {
kw_init();
first = 1;
}
i = nm[0];
if (i < FIRST_C || i > LAST_C)
return;
kp = kwstart[i-FIRST_C];
if (kp)
for (; kp->name; kp++) {
i = strcmp(nm, kp->name);
if (i == 0) {
tp->e_token = kp->kwval;
tp->e_flags = kp->kflags;
return;
} else if (i < 0)
return;
}
}
#if CC68
/* fix args since stupid lib makes all lower case */
upstr(s)
char *s;
{
while (*s) {
if (*s >= 'a' && *s <= 'z')
*s += 'A'-'a';
s++;
}
}
downstr(s)
char *s;
{
while (*s) {
if (*s >= 'A' && *s <= 'Z')
*s -= 'A'-'a';
s++;
}
}
#endif